package org.spamforces.dao.impl;

import org.jacuzzi.core.Row;
import org.spamforces.dao.EmailDao;
import org.spamforces.model.Email;

import java.util.*;

/**
 * @author IvanPopelyshev (ivan.popelyshev@gmail.com)
 */
public class EmailDaoImpl extends ApplicationDaoImpl<Email> implements EmailDao {
    @Override
    public Email find(long id) {
        return super.find(id);
    }

    @Override
    public List<Email> peek(int maxSize) {
        return findBy("status='QUEUE' LIMIT ?", maxSize);
    }

    @Override
    public boolean isAnythingInQueue(long broadcastId) {
        return (findBy("status='QUEUE' and broadcastId=? LIMIT 1", broadcastId)
                .size() > 0);
    }

    @Override
    public void update(Email e) {
        e.setSentTime(findNow());
        super.update(e);
    }

    @Override
    public Set<String> emailsDoneOrQueueByTargetBroadcastId(long broadcastId) {
        List<Row> rows = getJacuzzi().findRows("SELECT targetEmail FROM `Email` WHERE (status='QUEUE' OR status='DONE') AND broadcastId=?", broadcastId);

        Set<String> emails = new HashSet<>(rows.size());
        for (Row row : rows) {
            emails.add(Objects.toString(row.get("targetEmail")));
        }

        return Collections.unmodifiableSet(emails);
    }

    @Override
    public void insert(List<Email> objects) {
        super.insert(objects);
    }

    @Override
    public Statistics findStatisticsByBroadcastId(long broadcastId) {
        Statistics statistics = new Statistics();

        statistics.setQueueCount((int) getJacuzzi().findLong(
                "SELECT COUNT(*) FROM `Email` WHERE broadcastId=? AND status=?",
                broadcastId,
                "QUEUE"
        ));

        statistics.setFailedCount((int) getJacuzzi().findLong(
                "SELECT COUNT(*) FROM `Email` WHERE broadcastId=? AND status=?",
                broadcastId,
                "FAILED"
        ));

        statistics.setDoneCount((int) getJacuzzi().findLong(
                "SELECT COUNT(*) FROM `Email` WHERE broadcastId=? AND status=?",
                broadcastId,
                "DONE"
        ));

        return statistics;
    }
}
